const EventEmitter = require('events').EventEmitter;
const Websocket = require("ws");
const Logger  = require("../modules/logger.js");

let { log } = console;

const { Base_Client} = require('./class/Base_Client.js');

class WebsocketClient extends EventEmitter{
    constructor({name, connectUrl, connectKey, reconnectInterval, Client}){
        super();
        this.name = name;
        this.connectUrl = connectUrl;
        this.connectKey = connectKey;
        this.reconnectInterval = reconnectInterval;
        this.Client = Client;
        this.wsc_state = {
            readyReconnect: true,
            reconnect_num: 0
        };

        // 专用日志记录器
        this.logger = new Logger(name);
        // 客户端对象
        this.client = null;
        //this.listener = new Map();
        this.ws = null;
        //this.#connect(this);
        this.on('error', (wsclient, e)=>{});
    }

    connect(){
        this.ws = new Websocket(`${this.connectUrl}?key=${this.connectKey}`);
        this.client = this.Client ? new this.Client(this.ws) : new Base_Client(this.ws);
        this.wsc_state.readyReconnect = true; // 启用重连机制

        this.ws.on('open', ()=>{
            this.wsc_state["reconnect_num"] = 0; // 初始化
            this.logger.info(`>> WS连接成功: ${this.connectUrl}`);
            this.emit('open', this.client);
        });
        this.ws.on('message', (message_raw)=>{
            this.emit('message', this.client, message_raw);
        });
        this.ws.on("close", (code, reason)=>{
            if (this.wsc_state.readyReconnect){
                this.logger.error(`连接已丢失第 ${this.wsc_state["reconnect_num"]} 次 | 错误码: ${code} | 原因: ${reason} | ${this.connectUrl}`);
                setTimeout(()=>{ // 启动重连
                    if (this.wsc_state.readyReconnect){
                        this.ws.close();
                        this.wsc_state["reconnect_num"]++;
                        this.connect();
                    }
                }, this.reconnectInterval);
            }else{
                this.wsc_state["reconnect_num"] = 0;
            }
            this.emit('close', this.client, code, reason);
        });
        this.ws.on("error", (error)=>{
            if (!error.message.includes('ECONNREFUSED')){
                this.logger.error(error.message);
            }
            this.emit('error', this.client, error);
        });
    }

    close(){
        this.wsc_state.readyReconnect = false;
        this.ws.terminate();
        this.logger.info('● WS协调客户端已关闭');
    }
}
module.exports = WebsocketClient;